package com.m.job.server.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.client.job.core.model.MJob;
import com.client.job.core.model.MJobInstance;
import com.client.job.utils.BeanReflectUtils;
import com.client.job.utils.DataResult;
import com.client.job.utils.MJobUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.m.job.server.model.MJobInstanceDto;
import com.m.job.server.service.MJobInstanceService;
import com.m.job.server.service.MJobService;
import com.m.job.socket.WebSocketClient;
import com.m.utils.PageSearchDomain;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/server/jobInstance")
@Api(tags = "Job实例列表")
public class MJobInstanceController {

	@Autowired
	private MJobInstanceService mJobInstanceService;

	@Autowired
	private MJobService mJobService;

	@PostMapping("/list")
	@ApiOperation("查询Job列表")
	public DataResult list(@RequestBody PageSearchDomain<MJobInstanceDto> search) throws Exception {
		PageHelper.startPage(search.getPageNum(), search.getPageSize());
		PageInfo<MJobInstanceDto> page = new PageInfo<>(mJobInstanceService.findJobMachineList(search.getObj()));
		List<MJobInstanceDto> list = page.getList();
		// 构建整体的测试案例
		if (list == null || list.isEmpty()) {
			return DataResult.buildSuccess(page);
		}
		// 查询Mjob
		List<Map<String, Object>> res = new ArrayList<>();
		List<MJob> mJobList = mJobService
				.listJobByJobIds(list.stream().map(MJobInstance::getJobId).collect(Collectors.toList()));
		Map<String, List<MJob>> mapJob = mJobList.stream().collect(Collectors.groupingBy(MJob::getJobId));
		for (Entry<String, List<MJobInstanceDto>> e : list.stream().collect(Collectors.groupingBy(MJobInstanceDto::getJobId))
				.entrySet()) {
			List<MJob> mjs = mapJob.get(e.getKey());
			for (MJobInstance mi : e.getValue()) {
				Map<String, Object> instanceMap = BeanReflectUtils.beanProToListKv(mi);
				if (mjs != null) {
					MJob mj = new MJob();
					BeanUtils.copyProperties(mjs.get(0), mj);
					MJobUtils.analysisParams(mj, mi);
					instanceMap.put("params", mj.getParams());
				}
				res.add(instanceMap);
			}
		}
		PageInfo<?> newPage = new PageInfo<>(res);
		newPage.setTotal(page.getTotal());
		return DataResult.buildSuccess(newPage);
	}

	@PostMapping("/stopJobInstance")
	@ApiOperation("暂停实例")
	public DataResult stopJobInstance(@RequestBody Map<String, String> param) throws Exception {
		if (param.get("idList") == null || param.get("idList").isEmpty()) {
			return DataResult.buildFail("请选择数据");
		}
		mJobInstanceService.stopJobInstance(Arrays.asList(param.get("idList").split(",")));
		return DataResult.buildSuccess();
	}

	@PostMapping("/startJobInstance")
	@ApiOperation("开始实例")
	public DataResult startJobInstance(@RequestBody Map<String, String> param) throws Exception {
		if (param.get("idList") == null || param.get("idList").isEmpty()) {
			return DataResult.buildFail("请选择数据");
		}
		mJobInstanceService.startJobInstance(Arrays.asList(param.get("idList").split(",")));
		return DataResult.buildSuccess();
	}

	@PostMapping("/copyJobInstance")
	@ApiOperation("复制实例")
	public DataResult copyJobInstance(@RequestBody MJobInstanceDto mJobInstance) throws Exception {
		String newJobName = mJobInstance.getJobName();
		mJobInstance = mJobInstanceService.getJobInstanceById(mJobInstance.getMachineId());
		mJobInstance.setJobName(newJobName);
		if (!WebSocketClient.webSocketMap.keySet()
				.contains(MJobUtils.genServerFlag(mJobInstance.getAppName(), mJobInstance.getPort()))) {
			mJobInstanceService.delFormDb(mJobInstance.getMachineId());
			return DataResult.buildFail("该实例无法复制，可能应用端已经停止");
		}
		mJobInstanceService.copyJobInstance(mJobInstance);
		return DataResult.buildSuccess();
	}

	@PostMapping("/delJobInstance")
	@ApiOperation("删除实例")
	public DataResult delJobInstance(@RequestBody MJobInstance mJobInstance) throws Exception {
		mJobInstance = mJobInstanceService.getJobInstanceById(mJobInstance.getMachineId());
		if (mJobInstance == null) {
			return DataResult.buildFail("该实例不存在");
		}
		if (mJobInstance.getJobStatus() == 0) {
			return DataResult.buildFail("该实例正在运行中，无法删除");
		}

		if (!WebSocketClient.webSocketMap.keySet()
				.contains(MJobUtils.genServerFlag(mJobInstance.getAppName(), mJobInstance.getPort()))) {
			return DataResult.buildFail("该实例应用端停止");
		}
		mJobInstanceService.delFormDb(mJobInstance.getMachineId());
		return DataResult.buildSuccess();
	}

	@PostMapping("/newJobInstance")
	@ApiOperation("新增实例")
	public DataResult buildNew(@RequestBody MJobInstanceDto mJobInstance) throws Exception {
		if (!WebSocketClient.webSocketMap.keySet()
				.contains(MJobUtils.genServerFlag(mJobInstance.getAppName(), mJobInstance.getPort()))) {
			return DataResult.buildFail("无法链接该应用IP");
		}
		mJobInstanceService.addJobInstance(mJobInstance);
		return DataResult.buildSuccess();
	}

}
